package com.example.d9_homework.homework07;


import java.util.HashSet;
import java.util.Iterator;
import java.util.Set;
import java.util.regex.Pattern;

public class Test {
    // 正则表达式匹配身份证号：长度必须18位 数字0不能开头 除了最后一位中间不允许有数字Xx
    private static final Pattern ID_CARD_PATTERN = Pattern.compile("^[1-9]\\d{16}[\\dxX]$");

    public static void main(String[] args) {
        // 需求
        // (1)定义Set集合,存入多个字符串
        // (2)删除集合中不满足身份证号码的数据 身份证要求：长度必须18位 数字0不能开头 除了最后一位中间不允许有数字最后一位可以是数字或者Xx
        // (3)然后利用迭代器遍历集合元素并输出

        // 1.定义一个set集合存储用户的身份证号
        Set<String> idCards = new HashSet<>();
        idCards.add("123456789012345678"); // 不合法：以0开头
        idCards.add("22345678901234567X"); // 合法
        idCards.add("32345678901234567x"); // 合法
        idCards.add("423456789012345671"); // 合法
        idCards.add("52345678901234567");  // 不合法：长度不足18位
        idCards.add("62345678901234567XX");// 不合法：包含两个非数字字符

        // 使用stream流实现
        idCards.stream().filter(idCard -> idCard != null && // 检查身份证号码是否为空,确保不处理空值
                        idCard.length() == 18 && // 检查身份证号码的长度是否为18位,符合标准身份证号码的长度要求
                        idCard.charAt(0) != '0' && // 检查身份证号码的第一位是否不为0,避免无效的身份证号码
                        idCard.substring(0, 17).chars().allMatch(Character::isDigit) && // 检查前17位是否全部为数字,确保这部分符合数字要求
                        (Character.isDigit(idCard.charAt(17)) || idCard.charAt(17) == 'X' || idCard.charAt(17) == 'x')) // 检查第18位是否为数字或字母X/x,允许这两种情况
                .forEach(System.out::println); // 对于每个符合条件的身份证号码,打印到控制台

        System.out.println("-----------------------------------------------------");

        // 或者直接引用下面的静态方法
        idCards.stream().filter(Test::isValidIDCard).forEach(System.out::println);

        System.out.println("-----------------------------------------------------");

        // 使用正则表达式结合stream流
        idCards.stream().filter(idCard -> idCard.matches(ID_CARD_PATTERN.pattern())).forEach(System.out::println);

        System.out.println("-----------------------------------------------------");

        // 2.遍历集合中的数据找到不符合要求的数据,并删除
        Iterator<String> iterator = idCards.iterator();
        while (iterator.hasNext()) {
            String idCard = iterator.next();
            if (!isValidIDCard(idCard)) {
                iterator.remove(); // 注意这里一定要使用迭代器的方法删除,否则会出现并发修改异常的问题
            }
        }

        // 3.遍历集合元素并输出
        idCards.forEach(System.out::println);
    }

    /**
     * 判断身份证号码是否合法
     *
     * @param idCard 身份证号码
     * @return 返回true表示合法, 返回false表示不合法
     */
    private static boolean isValidIDCard(String idCard) {
        // 检查是否为null或长度不是18
        if (idCard == null || idCard.length() != 18) {
            return false;
        }

        // 第一个字符不能是'0'
        if (idCard.charAt(0) == '0') {
            return false;
        }

        // 中间16位必须是数字
        for (int i = 0; i < 17; i++) {
            char c = idCard.charAt(i);
            if (c < '0' || c > '9') {
                return false;
            }
        }

        // 最后一位可以是数字或者'X'/'x'
        char lastChar = idCard.charAt(17);
        if (!(lastChar >= '0' && lastChar <= '9' || lastChar == 'X' || lastChar == 'x')) {
            return false;
        }

        return true;
    }
}
